package com.edgar.plugin.utils;

import android.util.Log;

import java.lang.reflect.Field;

/**
 * Created by Edgar on 2018/2/1.
 */
public final class FieldUtils {

    private static final String TAG = "FieldUtils";
    private FieldUtils(){}

    public static Field findField(Class<?> clazz, String fieldName, boolean findSupportClass){
        try {
            return clazz.getDeclaredField(fieldName);
        } catch (NoSuchFieldException e) {
            Log.e(TAG,String.format("No such %s",fieldName),e);
            if (findSupportClass){
                return findField(clazz.getSuperclass(),fieldName,true);
            }
            return null;
        }
    }

    public static Object readField(Object object, String fieldName){
        return read(findField(object.getClass(),fieldName,false),object);
    }

    public static Object readField(Class<?> targetClass,Object object, String fieldName){
        return read(findField(targetClass,fieldName,false),object);
    }

    public static Object readStaticField(Class<?> targetClass,String fieldName){
        return readField(targetClass,null,fieldName);
    }

    public static Object read(Field field, Object object){
        try {
            if (field == null) return null;
            field.setAccessible(true);
            return field.get(object);
        } catch (IllegalAccessException e) {
            Log.e(TAG,String.format("%s illegal access",field.getName()),e);
            throw new RuntimeException(e);
        }
    }

    public static void writeStaticField(Class<?> targetClass,String fieldName,Object value){
        writeField(targetClass,null,fieldName,value);
    }

    public static void writeField(Class<?> targetClass,Object object,String fieldName,Object value){
        write(findField(targetClass,fieldName,false),object,value);
    }

    public static void writeField(Object object, String fieldName, Object value){
        write(findField(object.getClass(),fieldName,false),object,value);
    }

    public static void write(Field field, Object object, Object value){
        try {
            if (field != null){
                field.setAccessible(true);
                field.set(object,value);
            }
        } catch (IllegalAccessException e) {
            Log.e(TAG,String.format("%s illegal access",field.getName()),e);
            throw new RuntimeException(e);
        }
    }
}
